package com.tzy.user.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tzy.common.constant.*;
import com.tzy.common.controller.BaseController;
import com.tzy.common.entity.MyAssets;
import com.tzy.common.entity.User;
import com.tzy.common.utils.CalendarUtil;
import com.tzy.common.utils.EncryptUtil;
import com.tzy.user.service.AssetsServiceRPC;
import com.tzy.user.service.RedisService;
import com.tzy.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author 谭同学
 * @since 2022-02-28
 */
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController extends BaseController {
    @Resource
    private UserService userService;
    @Resource
    private AssetsServiceRPC assetsServiceRPC;
    @Resource
    private RedisService redisService;
    @Value("${file.upload.default-profile-photo}")
    private String defaultProfilePhoto;//默认头像路径

    @PostMapping("/assets/add")
    public Result add(@RequestBody MyAssets myAssets) {
        log.info("myAssets=" + myAssets);
        boolean save = assetsServiceRPC.save(myAssets);
        return Result.success(save);
    }

    /**
     * 使用验证码登录
     *
     * @param username
     * @param inputCheckCode
     * @return
     */
    @PostMapping("/login/with/verification/code")
    public WebResult loginWithVerificationCode(String username, String inputCheckCode) {
        log.info("username=" + username + ",inputCheckCode=" + inputCheckCode);
        //登录注册前看错误次数有没有大于6次,禁止注册
        //登录注册前判断邮箱验证码错误的次数,大于6次,则当天禁止注册, 把当前注册用户的邮箱拉入黑名单,
        int redisNumberOfErrors = 0;
        String cacheCheckCode = redisService.getString(CacheConstant.CACHE_CHECK_CODE + username);
        log.info("cacheCheckCode={},inputCheckCode={}", cacheCheckCode, inputCheckCode);
        if (inputCheckCode == null || inputCheckCode == "") {//用户输入的邮箱验证码为空时
            return new WebResult(WebResultMsgCode.FAIL).putData(CacheConstant.MESSAGE, "请输入验证码");
        } else if (cacheCheckCode == null || cacheCheckCode == "") {//生成的邮箱验证码为空时
            return new WebResult(WebResultMsgCode.FAIL).putData(CacheConstant.MESSAGE, "验证码已过期, 请重新获取验证码");
        } else if (!cacheCheckCode.equals(inputCheckCode)) {//验证码错误时,错误次数加 1
            //获取错误次数
            String cacheNumberOfErrors = redisService.getString(CacheConstant.CACHE_NUMBER_OF_ERRORS + username);
            //如果错误多次
            if (null != cacheNumberOfErrors) {
                //redis错误次数
                redisNumberOfErrors = Integer.parseInt(redisService.getString(CacheConstant.CACHE_NUMBER_OF_ERRORS + username));

                ++redisNumberOfErrors;
                log.info("++numberOfErrors=" + redisNumberOfErrors);
                if (redisNumberOfErrors <= 6) {
                    //错误六次以下//错误两次及以上
                    redisService.setString(CacheConstant.CACHE_NUMBER_OF_ERRORS + username, String.valueOf(redisNumberOfErrors), CalendarUtil.computationTime());
                    log.info("redis numberOfErrors=" + redisService.getString(CacheConstant.CACHE_NUMBER_OF_ERRORS + username));
                    return new WebResult(WebResultMsgCode.FAIL, CacheConstant.VERIFICATION_CODE_ERROR);
                } else if (redisNumberOfErrors > 6) {
                    return new WebResult(WebResultMsgCode.FAIL).putData(CacheConstant.MESSAGE, "验证码错误次数太多，请明天再试");
                }
            }
            //如果是第一次错误
            log.info("验证码第一次错误");
            redisService.setString(CacheConstant.CACHE_NUMBER_OF_ERRORS + username, String.valueOf(1), CalendarUtil.computationTime());
            return new WebResult(WebResultMsgCode.FAIL, CacheConstant.VERIFICATION_CODE_ERROR);
        }//验证码正确时
        User user = userService.loginWithVerificationCode(username);
        if (null != user) {
//            log.info(user.toString());
//            new Localdatetime
//            user.setLastLoginTime();
            boolean updateById = userService.updateById(user);
            return new WebResult(WebResultMsgCode.SUCCESS, user);
        } else {
            /**
             * 用户不存在,执行注册操作,注册送优惠券
             */
            log.info("username={},inputCheckCode={}", username, inputCheckCode);
            user = new User();
            user.setEmail(username);
            user.setInputCheckCode(inputCheckCode);
            int insert = userService.insert(user);
            int userId = user.getId();
            log.info("userId="+userId);
            if (!(insert > 0)) {
                return new WebResult(WebResultMsgCode.FAIL, false)
                        .putData(CacheConstant.MESSAGE, "注册失败");
            }
            return new WebResult(WebResultMsgCode.SUCCESS, user)
                    .putData(CacheConstant.MESSAGE, "注册成功")
                    .putData("userId",userId);
        }
    }
    /**
     * 使用密码登录
     *
     * @param username
     * @param password
     * @return
     */
    @PostMapping("/login/password")
//    public WebResult login(@RequestParam String username, @RequestParam String password) {
    public WebResult login(@RequestParam String username, @RequestParam String password) {

        User user = userService.loginByPassword(username, password);
        //用户被锁定
        if (user == null || StatusConstant.USER_STATUS_LOCKED != user.getStatus()) {
            if (user == null) {//密码输入错误; 6次密码错误之后，此账号当天不能再登录，提示“密码错误次数太多， 请明天再试”
                //自增错误次数并设置键的过期时间
                String stringIncorrectLoginPasswords = redisService.getString(CacheConstant.NUMBER_OF_INCORRECT_LOGIN_PASSWORDS + username);
                log.info("stringIncorrectLoginPasswords=" + stringIncorrectLoginPasswords);
                if (null != stringIncorrectLoginPasswords) {//不为空
                    redisService.setString(CacheConstant.NUMBER_OF_INCORRECT_LOGIN_PASSWORDS + username,
                            String.valueOf(Integer.parseInt(stringIncorrectLoginPasswords) + 1), CalendarUtil.computationTime());
                } else {//为空
                    redisService.setString(CacheConstant.NUMBER_OF_INCORRECT_LOGIN_PASSWORDS + username,
                            String.valueOf(1), CalendarUtil.computationTime());
                }
                //根据键获取自增后的值
                int incorrectLoginPasswords = Integer.parseInt(
                        redisService.getString(CacheConstant.NUMBER_OF_INCORRECT_LOGIN_PASSWORDS + username));
                log.info("incorrectLoginPasswords=" + incorrectLoginPasswords);
                if (incorrectLoginPasswords > 6) {//错误次数大于6
                    return new WebResult(WebResultMsgCode.TOO_MANY_PASSWORD_ERRORS);
                }//小于6
                return new WebResult(WebResultMsgCode.USER_PWD_ERROR);
            }
            return new WebResult(WebResultMsgCode.SUCCESS,user);
        } else {
            return new WebResult(WebResultMsgCode.USER_LOCKED);
        }
    }
    /**
     * 后台管理员登录
     * @param username
     * @param password
     * @return
     */
    @PostMapping("/admin/login")
    public WebResult adminLogin(@RequestParam String username, @RequestParam String password) {
        User user = userService.adminLogin(username, password);
        if (user == null){//如果用户记录不为空
            return new WebResult(WebResultMsgCode.USER_PWD_ERROR);
        } else if ( StatusConstant.USER_STATUS_LOCKED != user.getStatus() ) {//如果用户被锁定
            log.info("user="+user);
            //如果用户身份是管理员
            if ( user.getRoleId() == ( StatusConstant.ADMIN )) {
                return new WebResult(WebResultMsgCode.SUCCESS,user);
            } else {
                return new WebResult(WebResultMsgCode.NO_AUTH);
            }
        } else {
            return new WebResult(WebResultMsgCode.USER_LOCKED);
        }
    }
    @GetMapping("/info/userId")
    public WebResult getInfo(HttpServletRequest request) {
        int uid = getUserId(request);
        log.info("getInfo() uid=" + uid);
        User user = userService.getUserInfoById(uid);
        if (user != null) {
            //用户头像为空则设置默认头像
            if (user.getProfilePhotoUrl() == null){
                user.setProfilePhotoUrl(defaultProfilePhoto);
            }
//            user.getShippingAddress().split()
            return new WebResult(WebResultMsgCode.SUCCESS).putData("user", user);
        }
        return new WebResult(WebResultMsgCode.FAIL);
    }
    /**
     * 用户注册功能, 需要开启事务
     * @return
     */
    @PostMapping("/register")
    public WebResult insert(String email, String inputCheckCode) {

//        log.info("email=" + email + ",password=" + password+",inputCheckCode="+inputCheckCode);
        //注册前看错误次数有没有大于6次,禁止注册
        //注册前判断邮箱验证码错误的次数,大于6次,则当天禁止注册, 把当前注册用户的邮箱拉入黑名单,
        int numberOfErrors = 0;
        String cacheCheckCode = redisService.getString(CacheConstant.CACHE_CHECK_CODE + email);
        log.info("cacheCheckCode={},inputCheckCode={}", cacheCheckCode, inputCheckCode);
        if (inputCheckCode == null || inputCheckCode == "") {//用户输入的邮箱验证码为空时
            return new WebResult(WebResultMsgCode.SUCCESS).putData(CacheConstant.MESSAGE, "请输入验证码");
        } else if (cacheCheckCode == null || cacheCheckCode == "") {//生成的邮箱验证码为空时
            return new WebResult(WebResultMsgCode.SUCCESS).putData(CacheConstant.MESSAGE, "验证码已过期, 请重新获取验证码");
        } else if (!cacheCheckCode.equals(inputCheckCode)) {//验证码错误时,错误次数加 1
            //获取错误次数
            String cache = redisService.getString(CacheConstant.CACHE_NUMBER_OF_ERRORS + email);
            //如果错误多次
            if (null != cache) {
                //redis错误次数
                int redisNumberOfErrors = Integer.parseInt(redisService.getString(CacheConstant.CACHE_NUMBER_OF_ERRORS + email));

                ++redisNumberOfErrors;
                log.info("++numberOfErrors=" + redisNumberOfErrors);
                if (redisNumberOfErrors <= 6) {
                    //错误六次以下//错误两次及以上
                    redisService.setString(CacheConstant.CACHE_NUMBER_OF_ERRORS + email, String.valueOf(redisNumberOfErrors), CalendarUtil.computationTime());
                    log.info("redis numberOfErrors=" + redisService.getString(CacheConstant.CACHE_NUMBER_OF_ERRORS + email));
                    return new WebResult(WebResultMsgCode.SUCCESS).putData(CacheConstant.MESSAGE, CacheConstant.VERIFICATION_CODE_ERROR);
                } else if (redisNumberOfErrors > 6) {
                    return new WebResult(WebResultMsgCode.SUCCESS).putData(CacheConstant.MESSAGE, "验证码错误次数太多，请明天再试");
                }
            }
            //如果是第一次错误
            log.info("验证码第一次错误");
            redisService.setString(CacheConstant.CACHE_NUMBER_OF_ERRORS + email, String.valueOf(1), CalendarUtil.computationTime());
            return new WebResult(WebResultMsgCode.SUCCESS).putData(CacheConstant.MESSAGE, CacheConstant.VERIFICATION_CODE_ERROR);
        }//验证码正确时
        User user = new User();
        user.setEmail(email);
        //给用户设置默认头像
        user.setProfilePhotoUrl(defaultProfilePhoto);

        int insert = userService.insert(user);
        log.info("insert=" + insert);
        if (insert > 0) {
            return new WebResult(WebResultMsgCode.SUCCESS).putData(CacheConstant.MESSAGE, true);
        }
        return new WebResult(WebResultMsgCode.SUCCESS).putData(CacheConstant.MESSAGE, "注册失败");
    }

    /**
     * 修改密码
     *  PUT修改请求
     * @return
     */
    @PutMapping("/update")
    public Result updateUser(@RequestBody User user) {
        log.info("user="+user);
//        User user = new User();
//        user.setId(id);
//        user.setNickname(nickname);
        if( null != user ){
            if( null != user.getPassword()|| "" != user.getPassword() ){
                user.setPassword(EncryptUtil.getMd5(user.getPassword()));
            }
        }
        boolean updateById = userService.updateById(user);
        return updateById ? Result.success(true) : Result.failure(ResultCode.PARAM_NOT_COMPLETE);
    }
    @DeleteMapping("/delete")
    public Result delete(HttpServletRequest request) {
        int userId = getUserId(request);
        User user = new User();
        user.setId(userId);
        user.setStatus(1);
        boolean updateById = userService.updateById(user);
        if(updateById){
            return Result.success(updateById);
        }else{
            return Result.failure(ResultCode.REQUEST_ERROR);
        }

    }
    @GetMapping("/test")
    public Result testRedis(){
        return Result.success();
    }
}
